<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>顶点，顶点数据/颜色/法向量/索引（BufferGeometry）</title>
    <style>
      body {
        margin: 0;
        overflow: hidden;
        /* 隐藏body窗口区域滚动条 */
      }
    </style>
    <!--引入three.js三维引擎-->
    <!-- <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script> -->
    <!-- <script src="http://www.yanhuangxueyuan.com/threejs/build/three.js"></script> -->
    <!-- Three.js-master 包示例中的用法 examples/js/controls/OrbitControls.js  版本要匹配-->
    <script src="http://www.yanhuangxueyuan.com/3D/example/three.min.js"></script>
    <script src="../../util/OrbitControls.js"></script>
  </head>
  <body>
    <script type="module">
      // import { RAFTime } from "../../util/index.js";
      /**
       * 创建场景对象Scene
       */
      var scene = new THREE.Scene();

      /**
       * 辅助坐标系 参数250表示坐标系大小，可以根据场景大小去设置
       */
      var axisHelper = new THREE.AxisHelper(1000);
      scene.add(axisHelper);

      /**
       * 创建 BufferGeometry 实现自定义几何体（通过顶点数据）
       */
      var geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
      //类型数组创建顶点数据
      var vertices = new Float32Array([
        0,
        0,
        0, //顶点1坐标
        80,
        0,
        0, //顶点2坐标
        80,
        80,
        0, //顶点3坐标
        0,
        80,
        0, //顶点4坐标
      ]);
      // 创建属性缓冲区对象
      var attribue = new THREE.BufferAttribute(vertices, 3); //3个为一组，表示一个顶点的xyz坐标
      // 设置几何体attributes属性的位置属性
      geometry.attributes.position = attribue;

      //类型数组创建顶点颜色color数据
      var colors = new Float32Array([
        1,
        0,
        0, //顶点1颜色
        0,
        1,
        0, //顶点2颜色
        0,
        0,
        1, //顶点3颜色
        1,
        1,
        0, //顶点4颜色
      ]);
      // 设置几何体attributes属性的颜色color属性
      geometry.attributes.color = new THREE.BufferAttribute(colors, 3); //3个为一组,表示一个顶点的颜色数据RGB

      var normals = new Float32Array([
        0,
        0,
        1, //顶点1法向量
        0,
        0,
        1, //顶点2法向量
        0,
        0,
        1, //顶点3法向量
        0,
        0,
        1, //顶点4法向量
      ]);
      // 设置几何体attributes属性的位置normal属性
      geometry.attributes.normal = new THREE.BufferAttribute(normals, 3); //3个为一组,表示一个顶点的法向量数据

      // Uint16Array类型数组创建顶点索引数据
      var indexes = new Uint16Array([
        // 0对应第1个顶点位置数据、第1个顶点法向量数据
        // 1对应第2个顶点位置数据、第2个顶点法向量数据
        // 索引值3个为一组，表示一个三角形的3个顶点
        0, 1, 2, 0, 2, 3,
      ]);
      // 索引数据赋值给几何体的index属性
      geometry.index = new THREE.BufferAttribute(indexes, 1); //1个为一组

      // 三角面(网格)渲染模式
      var material = new THREE.MeshStandardMaterial({
        // color: 0x0000ff, //三角面颜色
        side: THREE.DoubleSide, //两面可见
        vertexColors: THREE.VertexColors, //以顶点颜色为准，三角形3点间进行颜色过渡
      }); //材质对象
      var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
      mesh.position.set(0, 0, 0);
      scene.add(mesh);

      // // 点渲染模式
      // var material = new THREE.PointsMaterial({
      //   // color: 0xff0000,
      //   vertexColors: THREE.VertexColors, //以顶点颜色为准
      //   size: 1.0, //点对象像素尺寸
      // }); //材质对象
      // var points = new THREE.Points(geometry, material); //点模型对象
      // scene.add(points); //点对象添加到场景中

      // // 线条渲染模式
      // var material = new THREE.LineBasicMaterial({
      //   // color: 0xff0000, //线条颜色
      //   vertexColors: THREE.VertexColors, //以顶点颜色为准，2点间的线段颜色过渡
      // }); //材质对象
      // var line = new THREE.Line(geometry, material); //线条模型对象
      // scene.add(line); //线条对象添加到场景中

      /**
       * 光源设置
       */
      //点光源
      var point = new THREE.PointLight(0xffffff);
      point.position.set(100, 200, 300); //点光源位置
      scene.add(point); //点光源添加到场景中
      //环境光
      var ambient = new THREE.AmbientLight(0x000);
      scene.add(ambient);
      // console.log(scene)
      // console.log(scene.children)
      /**
       * 相机设置
       */
      var width = window.innerWidth; //窗口宽度
      var height = window.innerHeight; //窗口高度
      var k = width / height; //窗口宽高比
      var s = 300; //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(60, 60, 60); //设置相机位置
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)

      /**
       * 创建渲染器对象
       */
      var renderer = new THREE.WebGLRenderer();
      renderer.setSize(width, height); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

      // 监听鼠标、键盘事件，实现 旋转/缩放/平移
      function render() {
        renderer.render(scene, camera); //执行渲染操作
      }
      // 启动渲染
      render();
      // 创建，轨迹控件
      var controls = new THREE.OrbitControls(camera, renderer.domElement);
      // 监听鼠标、键盘事件
      controls.addEventListener("change", render);
    </script>
  </body>
</html>
